package com.fish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fish.common.exception.BusinessException;
import com.fish.common.result.PageResult;
import com.fish.common.result.ResultCode;
import com.fish.common.util.UserContext;
import com.fish.dao.mapper.ChatMessageMapper;
import com.fish.dao.mapper.ChatSessionMapper;
import com.fish.dao.mapper.UserMapper;
import com.fish.model.dto.ChatMessageDTO;
import com.fish.model.dto.ChatMessageQueryDTO;
import com.fish.model.entity.ChatMessage;
import com.fish.model.entity.ChatSession;
import com.fish.model.entity.User;
import com.fish.model.vo.ChatMessageVO;
import com.fish.model.vo.ChatSessionVO;
import com.fish.service.ChatService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 聊天服务实现类
 *
 * @author fish
 */
@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService {

    private final ChatMessageMapper chatMessageMapper;
    private final ChatSessionMapper chatSessionMapper;
    private final UserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatMessageVO sendMessage(ChatMessageDTO chatMessageDTO) {
        Long senderId = UserContext.getUserId();
        Long receiverId = chatMessageDTO.getReceiverId();

        // 获取或创建会话
        Long sessionId = getOrCreateSession(senderId, receiverId);

        // 保存消息
        ChatMessage chatMessage = ChatMessage.builder()
                .sessionId(sessionId)
                .senderId(senderId)
                .receiverId(receiverId)
                .content(chatMessageDTO.getContent())
                .messageType(chatMessageDTO.getMessageType())
                .isRead(0)
                .build();
        chatMessageMapper.insert(chatMessage);

        // 更新会话信息
        updateSessionLastMessage(sessionId, chatMessageDTO.getContent(), senderId, receiverId);

        // 返回消息VO
        return convertToMessageVO(chatMessage);
    }

    @Override
    public List<ChatSessionVO> getSessionList() {
        Long currentUserId = UserContext.getUserId();

        // 查询当前用户的所有会话
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w.eq(ChatSession::getUserIdOne, currentUserId)
                .or()
                .eq(ChatSession::getUserIdTwo, currentUserId));
        wrapper.orderByDesc(ChatSession::getLastMessageTime);

        List<ChatSession> sessions = chatSessionMapper.selectList(wrapper);

        if (sessions.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取所有对方用户ID
        List<Long> otherUserIds = sessions.stream()
                .map(session -> {
                    if (session.getUserIdOne().equals(currentUserId)) {
                        return session.getUserIdTwo();
                    } else {
                        return session.getUserIdOne();
                    }
                })
                .collect(Collectors.toList());

        // 批量查询用户信息
        final Map<Long, User> userMap;
        if (!otherUserIds.isEmpty()) {
            userMap = userMapper.selectBatchIds(otherUserIds).stream()
                    .collect(Collectors.toMap(User::getId, user -> user));
        } else {
            userMap = new java.util.HashMap<>();
        }

        // 转换为VO
        return sessions.stream()
                .map(session -> {
                    Long otherUserId;
                    Integer unreadCount;

                    if (session.getUserIdOne().equals(currentUserId)) {
                        otherUserId = session.getUserIdTwo();
                        unreadCount = session.getUnreadCountOne();
                    } else {
                        otherUserId = session.getUserIdOne();
                        unreadCount = session.getUnreadCountTwo();
                    }

                    User otherUser = userMap.get(otherUserId);

                    return ChatSessionVO.builder()
                            .id(session.getId())
                            .otherUserId(otherUserId)
                            .otherUsername(otherUser != null ? otherUser.getUsername() : null)
                            .otherNickname(otherUser != null ? otherUser.getNickname() : null)
                            .otherAvatar(otherUser != null ? otherUser.getAvatar() : null)
                            .lastMessage(session.getLastMessage())
                            .lastMessageTime(session.getLastMessageTime())
                            .unreadCount(unreadCount)
                            .build();
                })
                .collect(Collectors.toList());
    }

    @Override
    public PageResult<ChatMessageVO> getMessageList(ChatMessageQueryDTO queryDTO) {
        Long currentUserId = UserContext.getUserId();
        Long sessionId = queryDTO.getSessionId();

        // 如果提供了对方用户ID，先获取或创建会话
        if (queryDTO.getOtherUserId() != null) {
            sessionId = getOrCreateSession(currentUserId, queryDTO.getOtherUserId());
        }

        if (sessionId == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "会话ID不能为空");
        }

        // 设置默认分页参数
        Integer pageNum = queryDTO.getPageNum() != null ? queryDTO.getPageNum() : 1;
        Integer pageSize = queryDTO.getPageSize() != null ? queryDTO.getPageSize() : 50;

        // 分页查询消息
        Page<ChatMessage> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ChatMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatMessage::getSessionId, sessionId);
        wrapper.orderByDesc(ChatMessage::getCreateTime);

        Page<ChatMessage> messagePage = chatMessageMapper.selectPage(page, wrapper);

        // 如果没有消息，直接返回空结果
        if (messagePage.getRecords().isEmpty()) {
            return PageResult.build(new ArrayList<>(), 0L, pageNum, pageSize);
        }

        // 获取所有相关用户ID
        List<Long> userIds = messagePage.getRecords().stream()
                .flatMap(message -> List.of(message.getSenderId(), message.getReceiverId()).stream())
                .distinct()
                .collect(Collectors.toList());

        // 批量查询用户信息
        final Map<Long, User> userMap;
        if (!userIds.isEmpty()) {
            userMap = userMapper.selectBatchIds(userIds).stream()
                    .collect(Collectors.toMap(User::getId, user -> user));
        } else {
            userMap = new java.util.HashMap<>();
        }

        // 转换为VO
        List<ChatMessageVO> messageVOList = messagePage.getRecords().stream()
                .map(message -> {
                    User sender = userMap.get(message.getSenderId());
                    User receiver = userMap.get(message.getReceiverId());

                    return ChatMessageVO.builder()
                            .id(message.getId())
                            .sessionId(message.getSessionId())
                            .senderId(message.getSenderId())
                            .senderUsername(sender != null ? sender.getUsername() : null)
                            .senderNickname(sender != null ? sender.getNickname() : null)
                            .senderAvatar(sender != null ? sender.getAvatar() : null)
                            .receiverId(message.getReceiverId())
                            .receiverUsername(receiver != null ? receiver.getUsername() : null)
                            .receiverNickname(receiver != null ? receiver.getNickname() : null)
                            .receiverAvatar(receiver != null ? receiver.getAvatar() : null)
                            .content(message.getContent())
                            .messageType(message.getMessageType())
                            .isRead(message.getIsRead())
                            .createTime(message.getCreateTime())
                            .build();
                })
                .collect(Collectors.toList());

        return PageResult.build(messageVOList, messagePage.getTotal(), pageNum, pageSize);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markMessagesAsRead(Long sessionId) {
        Long currentUserId = UserContext.getUserId();

        // 标记消息为已读
        LambdaUpdateWrapper<ChatMessage> messageWrapper = new LambdaUpdateWrapper<>();
        messageWrapper.eq(ChatMessage::getSessionId, sessionId);
        messageWrapper.eq(ChatMessage::getReceiverId, currentUserId);
        messageWrapper.eq(ChatMessage::getIsRead, 0);
        messageWrapper.set(ChatMessage::getIsRead, 1);
        chatMessageMapper.update(null, messageWrapper);

        // 更新会话未读数
        ChatSession session = chatSessionMapper.selectById(sessionId);
        if (session != null) {
            if (session.getUserIdOne().equals(currentUserId)) {
                session.setUnreadCountOne(0);
            } else if (session.getUserIdTwo().equals(currentUserId)) {
                session.setUnreadCountTwo(0);
            }
            chatSessionMapper.updateById(session);
        }
    }

    @Override
    public Long getOrCreateSession(Long userId1, Long userId2) {
        // 确保userId1 < userId2，保证唯一性
        Long minUserId = Math.min(userId1, userId2);
        Long maxUserId = Math.max(userId1, userId2);

        // 查询是否已存在会话
        LambdaQueryWrapper<ChatSession> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatSession::getUserIdOne, minUserId);
        wrapper.eq(ChatSession::getUserIdTwo, maxUserId);

        ChatSession session = chatSessionMapper.selectOne(wrapper);

        if (session == null) {
            // 创建新会话
            session = ChatSession.builder()
                    .userIdOne(minUserId)
                    .userIdTwo(maxUserId)
                    .unreadCountOne(0)
                    .unreadCountTwo(0)
                    .build();
            chatSessionMapper.insert(session);
        }

        return session.getId();
    }

    /**
     * 更新会话最后消息
     */
    private void updateSessionLastMessage(Long sessionId, String content, Long senderId, Long receiverId) {
        ChatSession session = chatSessionMapper.selectById(sessionId);
        if (session != null) {
            session.setLastMessage(content);
            session.setLastMessageTime(LocalDateTime.now());

            // 增加接收者的未读消息数
            if (session.getUserIdOne().equals(receiverId)) {
                session.setUnreadCountOne(session.getUnreadCountOne() + 1);
            } else if (session.getUserIdTwo().equals(receiverId)) {
                session.setUnreadCountTwo(session.getUnreadCountTwo() + 1);
            }

            chatSessionMapper.updateById(session);
        }
    }

    /**
     * 转换为消息VO
     */
    private ChatMessageVO convertToMessageVO(ChatMessage message) {
        User sender = userMapper.selectById(message.getSenderId());
        User receiver = userMapper.selectById(message.getReceiverId());

        return ChatMessageVO.builder()
                .id(message.getId())
                .sessionId(message.getSessionId())
                .senderId(message.getSenderId())
                .senderUsername(sender != null ? sender.getUsername() : null)
                .senderNickname(sender != null ? sender.getNickname() : null)
                .senderAvatar(sender != null ? sender.getAvatar() : null)
                .receiverId(message.getReceiverId())
                .receiverUsername(receiver != null ? receiver.getUsername() : null)
                .receiverNickname(receiver != null ? receiver.getNickname() : null)
                .receiverAvatar(receiver != null ? receiver.getAvatar() : null)
                .content(message.getContent())
                .messageType(message.getMessageType())
                .isRead(message.getIsRead())
                .createTime(message.getCreateTime())
                .build();
    }
}

